using System;
using System.Collections.Generic;
using System.ComponentModel;
using Microsoft.Ccr.Core;
using Microsoft.Dss.Core.Attributes;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Dss.ServiceModel.DsspServiceBase;
using W3C.Soap;
using Microsoft.Dss.Core.DsspHttp;
using vision = HCC.Robotics.Services.HCCGenericVisionModule.Proxy;

namespace HCC.Robotics.HCCRefereeModule
{
    public sealed class Contract
    {
        [DataMember]
        public const string Identifier = "http://www.hccrobotica.nl/2011/09/hccrefereemodule.html";
    }

    [DataContract]
    public class HCCRefereeModuleState
    {
        [DataMember]
        public GameConfig Configuration { get; set; }
        public GameState GameState { get; set; }
        public int TotalPlayers { get; set; }
        public bool Blue { get; set; }
        public bool Yellow { get; set; }
        // ID: 359
        public bool IsFirstHalf { get; set; }
        // ID: 359
    }

    #region Game Config

    [DataContract]
    public class GameConfig
    {
        [DataMember]
        public int FirstHalfTime { get; set; }
        [DataMember]
        public int HalfTime { get; set; }
        [DataMember]
        public int SecondHalfTime { get; set; }
        [DataMember]
        public int YellowCardTime { get; set; }
        [DataMember]
        public int TimeoutLimit { get; set; }
        [DataMember]
        public int NumberOfTimeouts { get; set; }
        private string _version = "1.0.0";
        [DataMember]
        public string Version
        {
            get { return _version; }
            set { _version = "1.0.0"; }
        }
    }

    [DataContract]
    public enum Team
    {
        Blue,
        Yellow
    }

    [DataContract]
    public enum GameState
    {
        Init,
        WaitingForPlayers,
        ReadyForGame,
        Playing,
        ResetGame
    }

    #region RefereeToPlayerModuleCommands

    [DataContract]
    public class PlayerData
    {
        #region Blue Team data
        [DataMember]
        public Position BluePlayer1 { get; set; }
        [DataMember]
        public Position BluePlayer2 { get; set; }
        [DataMember]
        public int BluePlayer1Heading { get; set; }
        [DataMember]
        public int BluePlayer2Heading { get; set; }
        #endregion
        #region Yellow Team data
        [DataMember]
        public Position YellowPlayer1 { get; set; }
        [DataMember]
        public Position YellowPlayer2 { get; set; }
        [DataMember]
        public int YellowPlayer1Heading { get; set; }
        [DataMember]
        public int YellowPlayer2Heading { get; set; }
        #endregion
        // ID: 359
        [DataMember]
        public bool IsFirstHalf { get; set; }   
        // ID: 359
    }

    [DataContract]
    public class BallData
    {
        [DataMember]
        public Position Ball { get; set; }
    }

    [DataContract]
    public class Position
    {
        [DataMember]
        public int X { get; set; }
        [DataMember]
        public int Y { get; set; }

        public Position(int x, int y)
        {
            X = x;
            Y = y;
        }
        public Position()
        {
        }
    }

    [DataContract]
    public class FieldDataClass
    {
        [DataMember]
        public Position LeftUpper { get; set; }
        [DataMember]
        public Position RightUpper { get; set; }
        [DataMember]
        public Position LeftLower { get; set; }
        [DataMember]
        public Position RightLower { get; set; }
        [DataMember]
        public Position LeftGoalUpper { get; set; }
        [DataMember]
        public Position LeftGoalLower { get; set; }
        [DataMember]
        public Position RightGoalUpper { get; set; }
        [DataMember]
        public Position RightGoalLower { get; set; }
    }

    [DataContract]
    public class GameStateDataClass
    {
        [DataMember]
        public bool BluePlayer1Active { get; set; }
        [DataMember]
        public bool BluePlayer2Active { get; set; }
        [DataMember]
        public bool YellowPlayer1Active { get; set; }
        [DataMember]
        public bool YellowPlayer2Active { get; set; }
    }

    #endregion

    #endregion

    [ServicePort]
    public class HCCRefereeModuleOperations : PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, HttpGet, Subscribe, SetColor, GameDataUpdate>
    {
    }

    public class Get : Get<GetRequestType, PortSet<HCCRefereeModuleState, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        public Get()
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        public Get(GetRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Get
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Get(GetRequestType body, PortSet<HCCRefereeModuleState, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }

    public class Subscribe : Subscribe<SubscribeRequestType, PortSet<SubscribeResponseType, Fault>>
    {
        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        public Subscribe()
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        public Subscribe(SubscribeRequestType body)
            : base(body)
        {
        }

        /// <summary>
        /// Creates a new instance of Subscribe
        /// </summary>
        /// <param name="body">the request message body</param>
        /// <param name="responsePort">the response port for the request</param>
        public Subscribe(SubscribeRequestType body, PortSet<SubscribeResponseType, Fault> responsePort)
            : base(body, responsePort)
        {
        }
    }

    public class SetColor : Update<SetColorRequest, PortSet<DefaultUpdateResponseType, Fault>>
    {
        /// <summary>
        /// Creates a new instance of SetColor
        /// </summary>
        public SetColor()
        {
        }

        /// <summary>
        /// Creates a new instance of SetColor
        /// </summary>
        /// <param name="body">the request message body</param>
        public SetColor(SetColorRequest body)
            : base(body)
        {
        }
    }

    public class GameDataUpdate : Update<GameDataUpdateRequest, PortSet<DefaultUpdateResponseType, Fault>>
    {
        public GameDataUpdate()
        {
        }
        public GameDataUpdate(GameData data)
            : base(new GameDataUpdateRequest(data))
        {
        }
    }

    [DataContract]
    public class GameDataUpdateRequest
    {
        public GameDataUpdateRequest()
        {
        }
        public GameDataUpdateRequest(GameData data)
        {
            Data = data;
        }
        [DataMember]
        public GameData Data { get; set; }
    }

    [DataContract]
    public class GameData
    {
        [DataMember]
        public DateTime TimeStamp { get; set; }
        [DataMember]
        public GameConfig Config { get; set; }
        [DataMember]
        public PlayerData Players { get; set; }
        [DataMember]
        public BallData Ball { get; set; }
        [DataMember]
        public GameStateDataClass State { get; set; }
        [DataMember]
        public FieldDataClass FieldData { get; set; }
    }

    [DataContract]
    [DataMemberConstructor]
    public class SetColorRequest
    {
        public SetColorRequest()
        { }
        public SetColorRequest(Team Team)
        {
            _team = Team;
        }
        private Team _team;
        [DataMember]
        public Team Team
        {
            get { return _team; }
            set { _team = value; }
        }
    }

    #region Windows forms communication

    public class FromWinformEvents : Port<FromWinformMsg>
    {
    }

    public class FromWinformMsg
    {
        public enum MsgEnum
        {
            Loaded,
            UpdateGameState,
            ActivePlayers,
            SetFirstHalf,
            SetSecondHalf,
            Exit
        }

        public string[] Parameters { get; set; }
        public MsgEnum Command { get; set; }
        public object Object { get; set; }

        public FromWinformMsg(MsgEnum command, string[] parameters)
        {
            Command = command;
            Parameters = parameters;
        }

        public FromWinformMsg(MsgEnum command, string[] parameters, object objectParam)
        {
            Command = command;
            Parameters = parameters;
            Object = objectParam;
        }
    }

    #endregion
}


